package dao

import (
	"fmt"
	_ "github.com/go-sql-driver/mysql"
	"go_src/common"
	_ "go_src/common"
	"go_src/common/exception"
	"strings"
)

type Announcement struct {
	Id       uint64 `db:"id" json:"id"`
	Content  string `db:"content" json:"content"`
	State    uint16 `db:"state" json:"state"`
	CreateAt int64  `db:"create_at" json:"create_at"`
	UpdateAt int64  `db:"update_at" json:"update_at"`
}

type AnnouncementDAO interface {
	SaveAnnouncement() common.Result

	SelectAnnouncement() common.Result

	SelectAnnouncementById() common.Result

	UpdateAnnouncementById() common.Result

	DeleteAnnouncementById() common.Result

	BatchDeleteAnnouncementsByIds(ids []string) common.Result
}

func (a *Announcement) SaveAnnouncement() common.Result {

	fieldValueMap := getNotNullFieldValueMap(*a, []string{})

	if len(fieldValueMap) == 0 {
		return common.Result{Success: false, Error: exception.BusinessError{Code: exception.ParamExceptionCode, Message: "参数错误"}}
	}

	var vals []string
	var keys []string
	for k, v := range fieldValueMap {
		keys = append(keys, k)
		vals = append(vals, v)
	}

	insertSql := fmt.Sprintf("insert into announcement (%s)values (%s)", strings.Join(keys, ","), strings.Join(vals, ","))
	ret, err := Db.Exec(insertSql)
	if err != nil {
		fmt.Println(err)
		return common.Result{Success: false, Error: exception.BusinessError{Code: exception.DbOperatorExceptionCode,
			Message: "数据库错误", OriginalError: err}}
	}
	n, err := ret.RowsAffected() // 操作影响的行数
	if err != nil {
		return common.Result{Success: false, Error: exception.BusinessError{Code: exception.DbOperatorExceptionCode,
			Message: "数据库错误", OriginalError: err}}
	}
	if n > 0 {
		return common.Result{Success: true}
	} else {
		return common.Result{Success: false}
	}
}

func (a *Announcement) SelectAnnouncement(pagination *common.Pagination) common.Result {

	whereSql := " 1=1 "
	if a.Id != 0 {
		whereSql += fmt.Sprintf("and id = %d ", a.Id)
	}
	if a.State != 0 {
		whereSql += fmt.Sprintf("and state = %d ", a.State)
	}
	if a.Content != "" {
		whereSql += fmt.Sprintf("and content like \"%%%s%%\" ", a.Content)
	}
	var announcements []Announcement

	var totalNum uint64
	err := Db.Get(&totalNum, "select count(1) from announcement where ? ", whereSql)
	if err != nil {
		return common.Result{Success: false, Error: exception.BusinessError{Code: exception.DbOperatorExceptionCode,
			Message: "数据库错误", OriginalError: err}}
	}
	pagination.Total = totalNum

	beginIndex := pagination.PerPage * (pagination.CurrentPage - 1)

	err = Db.Select(&announcements, "select * from announcement where ? limit ?,?", whereSql, beginIndex, pagination.PerPage)
	if err != nil {
		return common.Result{Success: false, Error: exception.BusinessError{Code: exception.DbOperatorExceptionCode,
			Message: "数据库错误", OriginalError: err}}
	}

	return common.Result{Success: true, Data: announcements}
}

func (a *Announcement) SelectAnnouncementById() common.Result {

	var announcements []Announcement
	err := Db.Select(&announcements, "select * from announcement where id=?", a.Id)
	if err != nil {
		return common.Result{Success: false, Error: exception.BusinessError{Code: exception.DbOperatorExceptionCode,
			Message: "数据库错误", OriginalError: err}}
	}

	return common.Result{Success: true, Data: announcements}
}

func (a *Announcement) UpdateAnnouncementById() common.Result {

	fieldValueMap := getNotNullFieldValueMap(*a, []string{"id"})

	if len(fieldValueMap) == 0 {
		return common.Result{Success: true}
	}

	var items []string
	for k, v := range fieldValueMap {
		items = append(items, k+"="+v)
	}

	updateSql := fmt.Sprintf("update announcement set %s where id = %d", strings.Join(items, ","), a.Id)
	fmt.Println(updateSql)
	ret, err := Db.Exec(updateSql)
	if err != nil {
		return common.Result{Success: false, Error: exception.BusinessError{Code: exception.DbOperatorExceptionCode,
			Message: "数据库错误", OriginalError: err}}
	}
	n, err := ret.RowsAffected() // 操作影响的行数
	if err != nil {
		return common.Result{Success: false, Error: exception.BusinessError{Code: exception.DbOperatorExceptionCode,
			Message: "数据库错误", OriginalError: err}}
	}
	if n > 0 {
		return common.Result{Success: true}
	} else {
		return common.Result{Success: false}
	}
}

func (a *Announcement) DeleteAnnouncementById() common.Result {

	deleteSql := fmt.Sprintf("delete from announcement where id = %d", a.Id)
	ret, err := Db.Exec(deleteSql)
	if err != nil {
		return common.Result{Success: false, Error: exception.BusinessError{Code: exception.DbOperatorExceptionCode,
			Message: "数据库错误", OriginalError: err}}
	}
	n, err := ret.RowsAffected() // 操作影响的行数
	if err != nil {
		return common.Result{Success: false, Error: exception.BusinessError{Code: exception.DbOperatorExceptionCode,
			Message: "数据库错误", OriginalError: err}}
	}
	if n > 0 {
		return common.Result{Success: true}
	} else {
		return common.Result{Success: false}
	}
}

func (a *Announcement) BatchDeleteAnnouncementsByIds(ids []string) common.Result {

	if len(ids) == 0 {
		return common.Result{Success: false, Error: exception.BusinessError{Code: exception.ParamExceptionCode,
			Message: "参数错误"}}
	}

	deleteSql := fmt.Sprintf("delete from announcement where id in (%s)", strings.Join(ids, ","))
	ret, err := Db.Exec(deleteSql)
	if err != nil {
		return common.Result{Success: false, Error: exception.BusinessError{Code: exception.DbOperatorExceptionCode,
			Message: "数据库错误", OriginalError: err}}
	}
	n, err := ret.RowsAffected() // 操作影响的行数
	if err != nil {
		return common.Result{Success: false, Error: exception.BusinessError{Code: exception.DbOperatorExceptionCode,
			Message: "数据库错误", OriginalError: err}}
	}
	if n > 0 {
		return common.Result{Success: true}
	} else {
		return common.Result{Success: false}
	}
}
